
/* 
 * File:   Packer.cpp
 * Author: saulio
 * Created on April 18, 2012, 3:12 PM
 */

#include "Frame.h"
#include <sys/msg.h>
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <stdio.h>
#include <string.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>


void imprimir(Package &pkg){
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"Tipo de mensaje:          | "<<int(pkg.header.type_message)<<std::endl;
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"Version:                  | "<< int(pkg.header.version)<<std::endl;
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"Numero de registro:       | "<<int(pkg.header.n_register) <<std::endl;
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"Dominio:                  | "<<int(pkg.header.domain)<<std::endl;
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"Id_s_dst:                 | " <<int(pkg.header.id_server_destination)<<std::endl;
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"Id_s_src:                 | " <<int(pkg.header.id_server_source)<<std::endl;
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"Flags:                    | "<<int(pkg.header.flag)<<std::endl;
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"Offset:                   | " <<int(pkg.header.offset)<<std::endl;
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"Tiempo de descarte:       | " <<int(pkg.f_time)<<std::endl;
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"ID_Cliente:               | " <<inet_ntoa(pkg.id_client.sin_addr)<<"::"<<ntohs(pkg.id_client.sin_port)<<std::endl;
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"ack:                      | " <<int(pkg.acknowledge_number)<<std::endl;
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"seq:                      | " <<int(pkg.sequence_number)<<std::endl;
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"N_seq:                    | " <<int(pkg.next_sequence_number)<<std::endl;
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"IP_Servidor_Guardian:     | " <<inet_ntoa(pkg.ip_server_guardian.sin_addr)<<std::endl;
    std::cout <<"-----------------------------------------------------"<<std::endl;
    std::cout <<"ID_Servidor_Guardian:     | " <<int(pkg.id_server_guardian)<<std::endl;
    std::cout <<"-----------------------------------------------------\n\n\n";
}


int main() {
    
    int packer_queue_id;
    Message_queue outbound_mail;
    
    struct msghdr mh;
    struct iovec v[1];
    struct sockaddr_in cli_addr;
    int sockfd, n_bytes_w;
    Package message;
    
    bzero((char *) &cli_addr, sizeof(cli_addr));
    bzero((char *) &message, sizeof(message));
    bzero((char *) &mh, sizeof(mh));
     
    packer_queue_id=Message_queue_setup(C_PACKER_QUEUE_KEY);
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    v[0].iov_base = &message;
    v[0].iov_len = sizeof(message);
   
    mh.msg_name = &cli_addr;
    mh.msg_namelen = sizeof(cli_addr);
    mh.msg_iov = v;
    mh.msg_iovlen = 1;
     
    std::cout <<"Inicializando el SERVIDOR DE EMPAQUETADO" << std::endl
               <<"El id del packer queue es: "<< packer_queue_id << std::endl;
     
    while(true){
       
         usleep(10000);
         if(msgrcv(packer_queue_id, (struct msgbuf *)&outbound_mail,
         sizeof(outbound_mail.package)+sizeof(outbound_mail.cli_addr),HIGHT_PRIORITY,IPC_NOWAIT)>0)
         {
             std::cout<<"Mensaje de alta prioridad"<<std::endl;
             message=outbound_mail.package;
             cli_addr.sin_addr.s_addr = outbound_mail.cli_addr.sin_addr.s_addr;
             cli_addr.sin_port = htons(QUIMERA_PORT);
             if ((n_bytes_w = sendmsg(sockfd, &mh, 0))< 0)
                 std::cout<<"Error al escribir el Socket"<<std::endl;
                 
             imprimir(outbound_mail.package);
         }
         
         else if(msgrcv(packer_queue_id, (struct msgbuf *)&outbound_mail,
         sizeof(outbound_mail.package)+sizeof(outbound_mail.cli_addr),MEDIUM_PRIORITY,IPC_NOWAIT)>0)
         {
             std::cout<<"Mensaje de media prioridad"<<std::endl;
             message=outbound_mail.package;
             cli_addr.sin_addr.s_addr = outbound_mail.cli_addr.sin_addr.s_addr;
             cli_addr.sin_port = htons(QUIMERA_PORT);
             if ((n_bytes_w = sendmsg(sockfd, &mh, 0))<0)
                 std::cout<<"Error al escribir el Socket"<<std::endl;
                 
             imprimir(outbound_mail.package);
         }
         
         else if(msgrcv(packer_queue_id, (struct msgbuf *)&outbound_mail,
         sizeof(outbound_mail)-sizeof(long),LOW_PRIORITY,IPC_NOWAIT)>0)
         {
             std::cout<<"Mensaje de baja prioridad"<< std::endl;
             message=outbound_mail.package;
             if (outbound_mail.package.header.type_message==BOOKMARK){
                 struct c *p;
                 p=(struct c*)&outbound_mail.data;
                  std::cout<<p<<std::endl;
             }
             cli_addr.sin_addr.s_addr = outbound_mail.cli_addr.sin_addr.s_addr;
             cli_addr.sin_port = htons(QUIMERA_PORT);
             
             if ((n_bytes_w = sendmsg(sockfd, &mh, 0))<0)
                 std::cout<<"Error al escribir el Socket"<<std::endl;
                 
             imprimir(outbound_mail.package);
         }  
        }
     close(sockfd);
     return (EXIT_FAILURE);  
}

